package com.xiaotu.spider.baidu.pageprocessor;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Optional;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.xiaotu.common.exception.SpiderException;
import com.xiaotu.common.exception.SpiderExceptionCode;
import com.xiaotu.common.model.NewsModel;
import com.xiaotu.common.util.Constants;
import com.xiaotu.common.util.DateUtils;
import com.xiaotu.common.util.GsonUtils;
import com.xiaotu.common.util.HtmlUtil;
import com.xiaotu.common.util.KeywordEncode;
import com.xiaotu.common.util.PageUtils;
import com.xiaotu.common.util.RegexUtils;
import com.xiaotu.common.util.SepratorUtil;
import com.xiaotu.common.util.StringUtil;
import com.xiaotu.common.util.TVProcessUtils;
import com.xiaotu.spider.APageProcessor;
import com.xiaotu.storage.converter.DateConverter;

import net.sf.json.JSONObject;
import us.codecraft.webmagic.Page;
import us.codecraft.webmagic.Request;
import us.codecraft.webmagic.selector.Html;

/**
 * @类名 TVBaiduPageProcessor
 * @日期 2017年2月15日
 * @作者 高海军
 * @功能 爬取电视剧的新闻
 */
@Component("TVBaiduPageProcessor")
public class TVBaiduPageProcessor extends APageProcessor
{

    private static final String SEARCH_URL = "https://www.baidu" +
            ".com/s?tn=baidurt&rtt=4&wd=%s&pnw=1&pbl=0&pbs=0&bsst=1&ie=utf-8";

    private static final String TIME_FLAG = "&nbsp;-&nbsp;";

    private static final int NEWS_DAY = 3;

    @Autowired
    private DateConverter converter;

    @Override
    public void process(Page page)
    {
        List<String> tableList = page.getHtml().xpath("//div[@id='content_left']/div/div[@class='result']").all();
        if (targetList == null || targetList.isEmpty())
            throw new SpiderException(SpiderExceptionCode.DataInvalideException);

        List<NewsModel> newsList = new ArrayList<>();
        tableList.forEach(tabStr ->
        {
            Html tabHtml = new Html(tabStr);
            String pubTime = tabHtml.xpath("//div[@class='c-summary c-row ']/div/p[@class='c-author']/text()").get();
            if(StringUtil.isEmpty(pubTime)){
            	pubTime = tabHtml.xpath("//div[@class='c-summary c-row ']/p[@class='c-author']/text()").get();
            }
            if(StringUtils.isNotEmpty(pubTime) && (pubTime.contains("年")&&pubTime.contains("月")&&pubTime.contains("日"))){
            	pubTime =pubTime.replace("年", "-").replace("月", "-").replace("日", "");
				try {
					pubTime = RegexUtils.regexSearch(RegexUtils.REGEX_DATE_TIME, pubTime);
					SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm");
					Date pubDate = format.parse(pubTime);
					if (org.apache.commons.lang3.time.DateUtils.addDays(pubDate, NEWS_DAY).before(org.apache.commons.lang3.time
							.DateUtils.truncate(new Date(), Calendar.DATE)))
						return;
				} catch (ParseException e) {
					e.printStackTrace();
				}
            }else{
            	pubTime = this.getPubTime(pubTime);
            }
            if (StringUtils.isEmpty(pubTime))
                return;
            String title = HtmlUtil.delHTMLTag(tabHtml.xpath("//h3[@class='c-title']/a").get());
            String url = tabHtml.xpath("//h3[@class='c-title']/a/@href").get();
            String content = HtmlUtil.delHTMLTag(tabHtml.xpath("//div[@class='c-summary c-row ']").get());
            String mediaName = tabHtml.xpath("//div[@class='c-summary c-row ']/div/p[@class='c-author']/text()").get();
            if(StringUtil.isEmpty(mediaName)){
            	mediaName =tabHtml.xpath("//div[@class='c-summary c-row ']/p[@class='c-author']/text()").get();
            }
            mediaName = HtmlUtil.delHTMLTag(mediaName);
            if (mediaName.indexOf(TIME_FLAG) > -1)
                mediaName = mediaName.substring(0, mediaName.indexOf(TIME_FLAG)).trim();

            Map<String, Object> objMap = page.getRequest().getExtras();
            newsList.add(new NewsModel(this.getNewsType(), objMap.get(this.getObjectIdField()).toString(), objMap.get
                    (this.getFieldKey()).toString(), title, url, content, mediaName, null, null, pubTime));
        });

        if (!newsList.isEmpty())
            page.putField(NewsModel.class.getName(), newsList);

        if (newsList.size() == tableList.size())
        {
            List<String> linkList = page.getHtml().xpath("//p[@id='page']/a[@class='n']").all();
            if (linkList == null || linkList.isEmpty())
                return;
            Optional<String> link = linkList.stream().filter(str -> str.contains("下一页")).map(str -> new Html(str)
                    .xpath("//a[@class='n']/@href").get()).findFirst();
            if (link.isPresent())
                PageUtils.addTargetRequest(page, link.get(), page.getRequest().getExtras());
        }
    }

    protected String getNewsType()
    {
        return NewsModel.NEWS_TV;
    }

    private String getPubTime(String pubTime)
    {
        try
        {
            pubTime = HtmlUtil.delHTMLTag(pubTime);
            if (StringUtils.isEmpty(pubTime) || pubTime.indexOf(TIME_FLAG) > -1)
                pubTime = pubTime.substring(pubTime.indexOf(TIME_FLAG) + TIME_FLAG.length()).trim();
            pubTime = this.converter.convert(pubTime, GsonUtils.fromJson("{timestamp:" + System.currentTimeMillis
                    () + "}", JSONObject.class), true).toString();
            Date pubDate = org.apache.commons.lang3.time.DateUtils.truncate(DateUtils.getDate(pubTime, DateUtils
                    .SECONDS_FORMAT), Calendar.DATE);
            if (!org.apache.commons.lang3.time.DateUtils.addDays(pubDate, NEWS_DAY).before(org.apache.commons.lang3.time
                    .DateUtils.truncate(new Date(), Calendar.DATE)))
                return pubTime;
            return null;
        }
        catch (Exception e)
        {
            return null;
        }
    }

    protected String getObjectIdField()
    {
        return "tvid";
    }

    protected String getFieldKey()
    {
        return "tvName";
    }

    @Override
    protected Request getStartRequest(JSONObject target)
    {
        return new Request(String.format(SEARCH_URL, KeywordEncode.encode(this.getKeyWord(target))));
    }

    protected String getKeyWord(JSONObject target)
    {
        String label = StringUtils.EMPTY;
        if (target.has("tvType"))
            label = SepratorUtil.SEP_SPACE_EN + TVProcessUtils.getTVTypeName(target.getString("tvType"));
        return target.getString(this.getFieldKey()) + label;
    }

    @Override
    public String getPageDataType(Page page)
    {
        return Constants.PageDataType.SEARCH_LIST;
    }

    @Override
    protected String getSpiderType()
    {
        return Constants.SpiderTaskType.TV_BAIDU;
    }
}
